package team.pwy.controller;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.*;
import team.pwy.pojo.entity.Seat;
import team.pwy.service.SeatService;
import team.pwy.vo.Result;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("seat")
public class SeatController {
    @Resource
    private SeatService seatService;

    @Resource
    private RedisTemplate redisTemplate;

    private DefaultRedisScript<Long> script;

    @PostConstruct
    public void init() {
        script = new DefaultRedisScript<>();
        script.setResultType(Long.class);
        script.setScriptSource(new ResourceScriptSource(new ClassPathResource("niceyoo.lua")));
    }

    /**
     * @param sessionId: 电影场次
     * @return Result
     * @author DaiLing
     * @description 查询选座界面座位信息
     * @date 2024/2/1 15:02
     */
    @GetMapping()
    public Result findByHallId(int sessionId) {
        List<Seat> seats = seatService.findByHallId(sessionId);
        return new Result("200", "查询成功", seats);
    }

    @GetMapping("{seatIds}")
    public Result findByIds(@PathVariable("seatIds") List<Integer> seatIds) {
        List<Seat> seats = seatService.findByIds(seatIds);
        return new Result("200", "查询成功", seats);
    }

    /**
     * @param userId:    用户ID
     * @param seatId:    座位ID
     * @param status:    状态码
     * @param sessionId: 场次ID
     * @return Result
     * @author DaiLing
     * @description 当用户进行选座
     * @date 2024/2/1 15:10
     */
    @PostMapping("{userId}/{seatId}/{status}/{sessionId}")
    public Result updateSeatStatus(@PathVariable("userId") int userId, @PathVariable("seatId") int seatId, @PathVariable("status") int status, @PathVariable("sessionId") int sessionId) {
        seatService.updateSeatStatus(userId, seatId, status, sessionId);
        return new Result();
    }

    /**
     * @param sessionId: 场次ID
     * @return Result
     * @author DaiLing
     * @description 用户重新进入页面
     * @date 2024/2/1 17:02
     */
    @PostMapping("/first/{sessionId}")
    public Result updateSeatFirst(@PathVariable("sessionId") int sessionId) {
        return new Result("200", "更新座位成功", seatService.updateSeatFirst(sessionId));

    }

    /**
     * @param userId:            用户ID
     * @param allSelectedSeatId: 该用户所有已选的ID
     * @param sessionId:         场次
     * @return Result
     * @author DaiLing
     * @description 用户离开页面，更新已选的座位状态
     * @date 2024/2/1 15:48
     */
    @PostMapping("/end/{userId}/{allSelectedSeatId}/{sessionId}")
    public Result updateSeatEnd(@PathVariable("userId") int userId, @PathVariable("allSelectedSeatId") List<Integer> allSelectedSeatId, @PathVariable("sessionId") int sessionId) {
        seatService.updateSeatEnd(userId, allSelectedSeatId, sessionId);
        return new Result();
    }

    @GetMapping("/look")
    public String test01(int id) {
        String key = "lock_" + id;
        //声明一个uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //获取锁
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, uuid, 10, TimeUnit.SECONDS);
        System.out.println(flag);
        if (flag) {//获取锁成功
            Object value = redisTemplate.opsForValue().get("num");
            // 如果是空直接返回
            if (value == null)
                return "error";
            // 不是空 如果说在这出现了异常！ 那么delete 就删除失败！ 也就是说锁永远存在！
            int num = Integer.parseInt(value + "");
            // 使num 每次+1 放入缓存
            redisTemplate.opsForValue().set("num", String.valueOf(++num));

            Long execute = (Long) redisTemplate.execute(script, Arrays.asList(key), uuid);
            System.out.println("execute执行结果，1表示执行del，0表示未执行 ===== " + execute);
        } else {
            System.out.println("获取锁失败!");
            try {
                //获取锁失败、每隔0.1秒再获取
                Thread.sleep(100);
                test01(id);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return "ok";
    }
}